<?php
namespace DB;
use Config\Base as Config;
use PDO;

/**
 * @author Evgeny Baranov <evgeny@baranov.eu>
 */
class DAO {
    /**
     * @var \DB\DAO
     */
    private static $instance;

    /**
     * @var \PDO
     */
    private $dbh;

    /**
     * @var \PDOStatement
     */
    private $stmt;


    /**
     * @return \DB\DAO
     */
    public static function getInstance() {
        if (!self::$instance) {
            self::$instance = new self;
        }

        return self::$instance;
    }

    private function __construct() {
        $cfg = Config::instance();
        $this->dbh = new PDO(
            'mysql:host=' . $cfg->mysql->host . ';dbname=' . $cfg->mysql->dbname,
            $cfg->mysql->user,
            $cfg->mysql->password);
        $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->dbh->exec("SET CHARACTER SET utf8");
    }


    /**
     * @param string $sql
     * @param array $bind
     * @return array:
     */
    public function query($sql, array $bind = array()) {
        $this->exec($sql, $bind);
        $result = $this->stmt->fetchAll(PDO::FETCH_ASSOC);
        return $result;
    }

    /**
     *
     * @param string $sql
     * @param array $bind
     */
    public function exec($sql, array $bind = array()) {
        if (!$this->stmt || $this->stmt->queryString != $sql) {
            $this->stmt = $this->dbh->prepare($sql);
        }

        foreach ($bind as $k => $v) {
            if (is_int($v)) {
                $t = PDO::PARAM_INT;
            } else {
                if (is_bool($v)) {
                    $t = PDO::PARAM_BOOL;
                } else {
                    if (is_null($v)) {
                        $t = PDO::PARAM_NULL;
                    } else {
                        if (is_string($v)) {
                            $t = PDO::PARAM_STR;
                        } else {
                            error_log($sql);
                            $t = FALSE;
                        }
                    }
                }
            }
            $this->stmt->bindParam(":{$k}", $bind[$k], $t);
        }

        $this->stmt->execute();
    }

    /**
     * @return string
     */
    public function lastInsertId() {
        return $this->dbh->lastInsertId();
    }
}

?>